/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufc.si.tcc.qmusic.model;

import br.ufc.si.tcc.qmusic.interfaces.IAcorde;
import br.ufc.si.tcc.qmusic.properties.Properties;
import br.ufc.si.tcc.qmusic.util.UtilQMusic;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Lucas Ismaily
 */
public class Tetrade extends Acorde implements IAcorde {

    private Triade triade;
    private Nota setima;
    //variável para sugerir trocar para evitar erro teorico (trocar setima por setimaEnarmonica)
    private Nota setimaEnarmonica;

    public Tetrade() {
    }

    public Tetrade(String tipo, Triade triade, Nota setima) {
        this.triade = triade;
        this.setima = setima;
        this.tipo = tipo;
    }

    public Tetrade(Triade triade, Nota setima) {
        this.triade = triade;
        this.setima = setima;
    }

    public Tetrade(Nota tonica, Nota terca, Nota quinta, Nota setima) {
        this.triade = new Triade(tonica, terca, quinta);
        this.setima = setima;
    }

    public Tetrade(String tipo, Nota tonica, Nota terca, Nota quinta, Nota setima) {
        this.tipo = tipo;
        this.triade = new Triade(tonica, terca, quinta);
        this.setima = setima;
    }

    @Override
    public Nota getSetimaEnarmonica() {
        return setimaEnarmonica;
    }

    @Override
    public boolean empty() {
        
        if(triade.empty() || (setima== null || setima.getNota().isEmpty())){
        return true;
        }
        return false;
        
    }
    @Override
    public void setSetimaEnarmonica(Nota setimaEnarmonica) {
        this.setimaEnarmonica = setimaEnarmonica;
    }

    @Override
    public Triade getTriade() {
        return triade;
    }

    @Override
    public void setTriade(Triade triade) {
        this.triade = triade;
    }

    @Override
    public Nota getSetima() {
        return setima;
    }

    @Override
    public void setSetima(Nota setima) {
        this.setima = setima;
    }

    @Override
    public boolean isTetradeMaior() {

        if(empty()){
        return false;
        }
        //salvar posição atual
        Triade triadeAtual = triade;
        Nota setimaAtual = setima;

        //notas em uma array para calcular as inversões (permutar notas)
        List<Nota> notas = new ArrayList<Nota>();
        notas.add(triade.getTonica());
        notas.add(triade.getTerca());
        notas.add(triade.getQuinta());
        notas.add(setima);


        for (int i = 0; i < 4; i++) {
            setima = notas.get(i);
            List<Nota> notasTriades = new ArrayList<Nota>();
            //recuperar as outras notas do array para compor a triade, iremos usar o metodo que permuta essas triades, da classe triade
            for (int j = 0; j < 4; j++) {
                if (j != i) {
                    notasTriades.add(notas.get(j));
                }
            }
            triade.setTonica(notasTriades.get(0));
            triade.setTerca(notasTriades.get(1));
            triade.setQuinta(notasTriades.get(2));

            if ((triade.isTriadeAumentada() || triade.isTriadeDiminuta() || triade.isTriadeMaior() || triade.isTriadeMenor())) {
                String setimaComp = UtilQMusic.getSetimaMaior(triade.getTonica()).getNota();
                if (setimaComp.equals(setima.getNota())) {
                    return true;
                }
            }
        }
        //caso não haja nenhuma tetrade, restauramos os valores e retornamos falso
        //para não atrapalhar a funçao que chama em ordem que as notas ocorram
        this.triade = triadeAtual;
        this.setima = setimaAtual;
        return false;
    }

    @Override
    //intervalo é de setima menor
    public boolean isTetradeMenor() {

         if(empty()){
        return false;
        }
        //salvar posição atual
        Triade triadeAtual = triade;
        Nota setimaAtual = setima;

        //notas em uma array para calcular as inversões (permutar notas)
        List<Nota> notas = new ArrayList<Nota>();
        notas.add(triade.getTonica());
        notas.add(triade.getTerca());
        notas.add(triade.getQuinta());
        notas.add(setima);


        for (int i = 0; i < 4; i++) {
            setima = notas.get(i);
            List<Nota> notasTriades = new ArrayList<Nota>();
            //recuperar as outras notas do array para compor a triade, iremos usar o metodo que permuta essas triades, da classe triade
            for (int j = 0; j < 4; j++) {
                if (j != i) {
                    notasTriades.add(notas.get(j));
                }
            }
            triade.setTonica(notasTriades.get(0));
            triade.setTerca(notasTriades.get(1));
            triade.setQuinta(notasTriades.get(2));

            if ((triade.isTriadeAumentada() || triade.isTriadeDiminuta() || triade.isTriadeMaior() || triade.isTriadeMenor())) {
                String setimaComp = UtilQMusic.getSetimaMenor(triade.getTonica()).getNota();
                if (setimaComp.equals(setima.getNota())) {
                    return true;
                }
            }
        }
        //caso não haja nenhuma tetrade, restauramos os valores e retornamos falso
        //para não atrapalhar a funçao que chama em ordem que as notas ocorram
        this.triade = triadeAtual;
        this.setima = setimaAtual;
        return false;
    }

    @Override
    public boolean isTetradeEnarmonica() {
 if(empty()){
        return false;
        }
        //salvar posição atual
        Triade triadeAtual = triade;
        Nota setimaAtual = setima;

        //notas em uma array para calcular as inversões (permutar notas)
        List<Nota> notas = new ArrayList<Nota>();
        notas.add(triade.getTonica());
        notas.add(triade.getTerca());
        notas.add(triade.getQuinta());
        notas.add(setima);
        for (int i = 0; i < 4; i++) {
            setima = notas.get(i);
            List<Nota> notasTriades = new ArrayList<Nota>();
            //recuperar as outras notas do array para compor a triade, iremos usar o metodo que permuta essas triades, da classe triade
            
            for (int j = 0; j < 4; j++) {
                if (j != i) {
                    notasTriades.add(notas.get(j));
                }
            }
            triade.setTonica(notasTriades.get(0));
            triade.setTerca(notasTriades.get(1));
            triade.setQuinta(notasTriades.get(2));

            if (isTetradeEnarmonicaTipos(Properties.MAIOR)) {
                return true;
            }
            if (isTetradeEnarmonicaTipos(Properties.MENOR)) {
                return true;
            }
        }
        //caso não haja nenhuma tetrade, restauramos os valores e retornamos falso
        //para não atrapalhar a funçao que chama em ordem que as notas ocorram
        this.triade = triadeAtual;
        this.setima = setimaAtual;
        return false;
    }

    private boolean isTetradeEnarmonicaTipos(String tipo) {


        boolean hasEnarmonia = false;

        //calcula a nota certa para
        String setimaComp = null;


        if (this.triade != null && this.triade.isTriadeEnarmonica()) {
            hasEnarmonia = true;
        } else if (!this.triade.isTriadeMaior() && !this.triade.isTriadeMenor() && !this.triade.isTriadeAumentada()
                && !this.triade.isTriadeDiminuta()) {
            return false;
        }
        if (tipo.equals(Properties.MAIOR)) {
            setimaComp = UtilQMusic.getSetimaMaior(triade.getTonica()).getNota();
        }
        if (tipo.equals(Properties.MENOR)) {
            setimaComp = UtilQMusic.getSetimaMenor(triade.getTonica()).getNota();
        }
        List<Nota> notasEnarmonicaTerca = UtilQMusic.getNotasEnarmonica(new Nota(setimaComp));
        for (Nota n : notasEnarmonicaTerca) {
            if (n.getNota().equals(this.setima.getNota())) {
                this.setimaEnarmonica = new Nota(setimaComp);
                hasEnarmonia = true;
                break;
            }
        }
        if (hasEnarmonia) {
            return true;
        }
        return false;
    }

    @Override
    public String getNotacaoABC() {

        if (isTetradeMaior() || isTetradeEnarmonicaTipos(Properties.MAIOR)) {
            return this.triade.getNotacaoABC() + "(7M)";
        }
        if (isTetradeMenor() || isTetradeEnarmonicaTipos(Properties.MENOR)) {
            return this.triade.getNotacaoABC() + "(7m)";
        }

        return null;


    }

    //Métodos das Triades
    @Override
    public Nota getQuinta() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setQuinta(Nota quinta) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Nota getTerca() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setTerca(Nota terca) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Nota getTonica() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setTonica(Nota tonica) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isTriadeEnarmonica() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Nota getEnarmonicaQuinta() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setEnarmonicaQuinta(Nota enarmonicaQuinta) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Nota getEnarmonicaTerca() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setEnarmonicaTerca(Nota enarmonicaTerca) {
        throw new UnsupportedOperationException("Not supported yet.");
    }


    
}
